/*
 * Ganesa Copyright (C) 2008 Wim Crols <twimpiex@gnx.be>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package be.gnx.ganesa.application.ui.widget;

import java.util.Vector;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;

public class SlippyMapPanAndZoom extends Composite {

  private Vector<SelectionListener> selectionListeners = new Vector<SelectionListener>();

  private int minimumZoomLevel = 0;

  private int maximumZoomLevel = 17;

  private int currentZoomLevel = 0;

  private Image up;

  private Image right;

  private Image down;

  private Image left;

  public SlippyMapPanAndZoom(Composite parent, int style) {
    super(parent, style);

    resize();

    SlippyMapPanAndZoom.this.addPaintListener(new PaintListener() {
      public void paintControl(PaintEvent paintEvent) {
        SlippyMapPanAndZoom.this.paintControl(paintEvent.gc);
      }
    });

    addDisposeListener(new DisposeListener() {
      public void widgetDisposed(DisposeEvent disposeEvent) {
        SlippyMapPanAndZoom.this.dispose();
      }
    });

    addControlListener(new ControlAdapter() {
      @Override
      public void controlResized(ControlEvent controlEvent) {
        SlippyMapPanAndZoom.this.resize();
      }
    });

  }

  private void paintControl(GC gc) {
    gc.drawImage(up, getClientArea().width / 3, 0);
    gc.drawImage(right, (getClientArea().width * 2) / 3, getClientArea().width / 3);
    gc.drawImage(down, getClientArea().width / 3, (getClientArea().width * 2) / 3);
    gc.drawImage(left, 0, getClientArea().width / 3);
  }

  public void dispose() {
    return;
  }

  protected void resize() {
    int elementWidth = getClientArea().width / 3;
    if (elementWidth > 0) {
      System.err.println("elementWdith = " + elementWidth);
      up = new Image(getDisplay(), new Rectangle(0, 0, elementWidth, elementWidth));
      GC gc = new GC(up);
      gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
      gc.drawLine(0, 0, elementWidth - 1, 0);
      gc.drawLine(elementWidth - 1, 0, elementWidth - 1, elementWidth - 1);
      gc.drawLine(elementWidth - 1, elementWidth - 1, 0, elementWidth - 1);
      gc.drawLine(0, elementWidth - 1, 0, 0);
      gc.drawLine(elementWidth / 2, elementWidth / 4, elementWidth / 2, (elementWidth * 3) / 4);
      gc.drawLine(elementWidth / 2, elementWidth / 4, elementWidth / 4, elementWidth / 2);
      gc.drawLine(elementWidth / 2, elementWidth / 4, (elementWidth * 3) / 4, elementWidth / 2);
      gc.dispose();

      right = new Image(getDisplay(), new Rectangle(0, 0, elementWidth, elementWidth));
      gc = new GC(right);
      gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
      gc.drawLine(0, 0, elementWidth - 1, 0);
      gc.drawLine(elementWidth - 1, 0, elementWidth - 1, elementWidth - 1);
      gc.drawLine(elementWidth - 1, elementWidth - 1, 0, elementWidth - 1);
      gc.drawLine(0, elementWidth - 1, 0, 0);
      gc.drawLine(elementWidth / 4, elementWidth / 2, (elementWidth * 3) / 4, elementWidth / 2);
      gc.drawLine((elementWidth * 3) / 4, elementWidth / 2, elementWidth / 2, elementWidth / 4);
      gc.drawLine((elementWidth * 3) / 4, elementWidth / 2, elementWidth / 2, (elementWidth * 3) / 4);
      gc.dispose();

      down = new Image(getDisplay(), new Rectangle(0, 0, elementWidth, elementWidth));
      gc = new GC(down);
      gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
      gc.drawLine(0, 0, elementWidth - 1, 0);
      gc.drawLine(elementWidth - 1, 0, elementWidth - 1, elementWidth - 1);
      gc.drawLine(elementWidth - 1, elementWidth - 1, 0, elementWidth - 1);
      gc.drawLine(0, elementWidth - 1, 0, 0);
      gc.drawLine(elementWidth / 2, elementWidth / 4, elementWidth / 2, (elementWidth * 3) / 4);
      gc.drawLine(elementWidth / 2, (elementWidth * 3) / 4, elementWidth / 4, elementWidth / 2);
      gc.drawLine(elementWidth / 2, (elementWidth * 3) / 4, (elementWidth * 3) / 4, elementWidth / 2);
      gc.dispose();

      left = new Image(getDisplay(), new Rectangle(0, 0, elementWidth, elementWidth));
      gc = new GC(left);
      gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
      gc.drawLine(0, 0, elementWidth - 1, 0);
      gc.drawLine(elementWidth - 1, 0, elementWidth - 1, elementWidth - 1);
      gc.drawLine(elementWidth - 1, elementWidth - 1, 0, elementWidth - 1);
      gc.drawLine(0, elementWidth - 1, 0, 0);
      gc.drawLine((elementWidth * 3) / 4, elementWidth / 2, elementWidth / 4, elementWidth / 2);
      gc.drawLine(elementWidth / 4, elementWidth / 2, elementWidth / 2, elementWidth / 4);
      gc.drawLine(elementWidth / 4, elementWidth / 2, elementWidth / 2, (elementWidth * 3) / 4);
      gc.dispose();
    }
  }

  public void addSelectionListener(SelectionListener selectionListener) {
    if (selectionListener != null) {
      selectionListeners.add(selectionListener);
    }
  }

  public void removeSelectionListener(SelectionListener selectionListener) {
    if ((selectionListener != null) && (selectionListeners.contains(selectionListener))) {
      selectionListeners.remove(selectionListener);
    }
  }

  public int getMinimumZoomLevel() {
    return minimumZoomLevel;
  }

  public void setMinimumZoomLevel(int minimumZoomLevel) {
    this.minimumZoomLevel = minimumZoomLevel;
  }

  public int getMaximumZoomLevel() {
    return maximumZoomLevel;
  }

  public void setMaximumZoomLevel(int maximumZoomLevel) {
    this.maximumZoomLevel = maximumZoomLevel;
  }

  public int getCurrentZoomLevel() {
    return currentZoomLevel;
  }

  public void setCurrentZoomLevel(int currentZoomLevel) {
    this.currentZoomLevel = currentZoomLevel;
  }

}